﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_Components.h".
//-------------------------------------------------------------------
/*
	Description:
			[ru]	Содержит основные физические константы, функции для их расчета
					и функции конвертации. Все константы имеют размерность в единицах СИ.
*/

#ifndef _UXS_PHYSICS_CONSTANTS_H
#define _UXS_PHYSICS_CONSTANTS_H

#pragma once

#include "../../stl_core/ux_stl_core.h"

namespace UX_STL
{
namespace UXPhysics
{
	using namespace UXTypes;
	using namespace UXMath;
	


//-------------------------------------------------------------------
// SI convertation

	template <typename T>	inline T MetersToInch(const T& x = T(1))	{ return ( x / T(0.0254) ); }		// m
	template <typename T>	inline T InchToMeters(const T& x = T(1))	{ return ( x * T(0.0254) ); }		// inch



//-------------------------------------------------------------------
// Molecular Physics

	// K <-> C
	template <typename T>	inline T CelsiusToKelvin(const T& x = T(0))	{ return ( x + T(273.15) ); }	// K
	template <typename T>	inline T KelvinToCelsius(const T& x = T(0))	{ return ( x - T(273.15) ); }	// C
	
	// mmHg <-> Pa
	template <typename T>	inline T MmHgToPa(const T& x = T(1))		{ return ( x * T(133.322) ); }	// Pa
	template <typename T>	inline T PaToMmHg(const T& x = T(1))		{ return ( x / T(133.322) ); }	// mmHg

	// atm <-> Pa
	template <typename T>	inline T AtmosphereToPa(const T& x = T(1))	{ return ( x * T(101325.0) ); }	// Pa
	template <typename T>	inline T PaToAtmosphere(const T& x = T(1))	{ return ( x / T(101325.0) ); }	// atm
	

	template <typename T>	constexpr	inline T AirMolarMass()			{ return T( 0.02898 ); }		// kg / mol
	template <typename T>	constexpr	inline T WaterMolarMass()		{ return T( 0.01801528 ); }		// kg / mol
	template <typename T>	constexpr	inline T GasConst()				{ return T( 8.3144621 ); }		// J / K * mol
	template <typename T>	constexpr	inline T BoltzmannConst()		{ return T( 1.380648813e-23 ); } // J / K


/*
=================================================
	парциальное давление насыщенного пара
	(для температур от −10 °C до 50 °C)
=================================================
*/
	template <typename T>
	inline T PartialPressureOfSaturatedSteam(const T& temperatureK)
	{
		return T(6.1078) * Pow( T(10), ( T(7.5) * temperatureK - T(2048.625) ) / ( temperatureK - T(35.85) ) );
	}
	
/*
=================================================
	давление водяного пара
	(для температур от −10 °C до 50 °C)
=================================================
*/
	template <typename T>
	inline T WaterVaporPressure(const T& tAirHumidity, const T& temperatureK)
	{
		return tAirHumidity * PartialPressureOfSaturatedSteam( temperatureK );
	}
	
/*
=================================================
	расчитать скорость звука в воздухе
=================================================
*/
	template <typename T>
	inline T SpeedOfSoundInAir(const T& temperatureK)
	{
		return Sqrt( T(1.4) * GasConst<T>() * temperatureK / AirMolarMass<T>() );
	}
	
/*
=================================================
	расчитать скорость звука в воде
	(по упрощённой формуле Лероя,
	 точность порядка 0,1 м/с для T < 20 °C и depth < 8 000 м)
=================================================
*/
	template <typename T>
	inline T SpeedOfSoundInWater(const T& temperatureK, const T& depth, const T& salinity)
	{
		const T	t_sub_10	= KelvinToCelsius( temperatureK ) - T(10);
		const T	t_sub_18	= KelvinToCelsius( temperatureK ) - T(18);
		const T	t_sub_35	= salinity - T(35);

		return	T(1492.9) + T(3) * t_sub_10 - T(0.006) * Square( t_sub_10 ) -
				T(0.04) * Square( t_sub_18 ) + T(1.2) * t_sub_35 -
				T(0.01) * t_sub_18 * t_sub_35 + depth / T(61);
	}



	
//-------------------------------------------------------------------
// Astrophysics

	template <typename T>	constexpr	inline T SpeedOfLight()			{ return T( 299792458.0 ); }	// 299 792 458 m
	template <typename T>	constexpr	inline T GravitationalConst()	{ return T( 6.6738480e-11 ); }	// 6,67384(80)*10^11  N*(m*kg)^2
	template <typename T>	constexpr	inline T AstronomicalUnit()		{ return T( 149597870660.0 ); }	// 149 597 870 660 m
	template <typename T>	constexpr	inline T Parsec()				{ return T( 3.08568e+16 ); }	// 3,08568*10^16 m
	template <typename T>	constexpr	inline T MassOfEarth()			{ return T( 5.9736e+24 ); }		// 5,9736*10^24 kg
	template <typename T>	constexpr	inline T MassOfSolar()			{ return T( 1.98892e+30 ); }	// 1,98892*10^30 kg
	template <typename T>	constexpr	inline T EarthGravity()			{ return T( 9.80665 ); }		// m/s*s
	
	
/*
=================================================
	ускорение свободного падения на Земле
	(latitude - широта,
	 height - высота над уровнем моря)
=================================================
*/
	template <typename T>
	inline T GravityOfEarth(const T& latitude, const T& height)
	{
		return ( T(9.780327) * ( T(1) + T(0.0053024) * Square( Sin( latitude ) ) +
				 T(0.0000058) * Square( Sin( latitude * T(2) ) ) ) - T(3.086e-6) * height );
	}
	
/*
=================================================
	ускорение свободного падения
=================================================
*/
	template <typename T>
	inline T GravitationalAcceleration(const T& mass, const T& radius)
	{
		return GravitationalConst<T>() * mass / Square( radius );
	}

//-------------------------------------------------------------------

}	// UXPhysics
}	// UX_STL

#endif	// _UXS_PHYSICS_CONSTANTS_H